import os.path
import json
import requests
import sys
import time
import win32con
import win32print
import win32ui


login_url     = 'https://cpc.csgrandeur.cn/cpcsys/contest/contest_auth_ajax'
rank_list_url = 'https://cpc.csgrandeur.cn/cpcsys/contest/ranklist_ajax'
g_username    = 'bmamanger' # 公网，开发用
g_password    = ''
g_contest_id  = '1018' # 竞赛ID，与CCPC-OJ系统一致
balloon_dir   = 'C:\\CCPC\\balloon' # 记录已打印的标签。

if True: # 内网热身赛
  login_url     = 'http://192.168.0.200:20080/cpcsys/contest/contest_auth_ajax'
  rank_list_url = 'http://192.168.0.200:20080/cpcsys/contest/ranklist_ajax'
  g_username    = 'bmanager'
  g_password    = ''
  g_contest_id  = '1001'
  if True: # 内网正式赛
    g_password = ''
    g_contest_id = '1005' # 不一定和热身赛连续


def hdc_print(info):
  font_set = {'name': 'Consolas', 'height': 512}
  font = win32ui.CreateFont(font_set)

  INCH = 1440 # 每英寸1440点，字体512点看着比较合适
  area = (0, INCH * 0, INCH * 4, INCH * -2)
  hdc = win32ui.CreateDC()
  # 标签打印机应预设为默认打印机
  hdc.CreatePrinterDC(win32print.GetDefaultPrinter())
  hdc.StartDoc('doc-' + info) # 开个临时文档名
  hdc.StartPage()
  hdc.SetMapMode(win32con.MM_TWIPS) 
  hdc.SelectObject(font)
  hdc.DrawText(info, area, win32con.DT_LEFT)
  hdc.EndPage()
  hdc.EndDoc()


def login(contest_id, team_id, password):
  global login_url
  hdr = { # OJ规定
    "X-Requested-With": "XMLHttpRequest",
  }
  form_args = {
    'cid': contest_id,
    'team_id': team_id,
    'password': password,
  }
  print(login_url, hdr, form_args)
  # 登录用post方法，form格式
  rsp = requests.post(login_url, headers=hdr, data=form_args)
  print('login:', rsp.status_code)
  if rsp.status_code == 200:
    return rsp.cookies
  else:
    print('login failed:', rsp)


problems = "ABCDEFGHIJKLM" # 题号，按需设置


def rank_list(cookies, contest_id):
  global rank_list_url 
  hdr = {
    "X-Requested-With": "XMLHttpRequest",
  }
  rank_list_url = rank_list_url + '?cid=' + contest_id
  # 榜单用get方法
  rsp = requests.get(rank_list_url, headers=hdr, cookies=cookies)
  htm = rsp.content.decode()

  rank_list_file = os.path.join(balloon_dir, 'rank_list.json')
  if htm.startswith('[{'): # 开头像JSON，想必成功
    # 存一份调试用
    with open(rank_list_file, "w", encoding="UTF-8") as ofs:
      ofs.write(htm)
  else:
    print('get rank failed:', htm)
    return

  ranks = json.loads(htm)
  cnt = 0
  for r in ranks: # r是一个参赛队的排行记录
    for p in problems: # 遍历题号
      # 如果r队提交过[p]题，并且ac属性（过题秒数）非空，表示通过
      if p in r and r[p]['ac'] is not None:
        # 存档文件
        file_name = r['user_id'] + '-' + p + '.txt'
        # 标签内容，形如A23-K
        tag = r['user_id'] + '-' + p
        if r[p]['pst'] == 3: # 首杀标记-FIRST。非首杀则pst为2
          tag = tag + '-FIRST'
        path = os.path.join(balloon_dir, file_name)
        if os.path.exists(path): # 文件存在，已处理过
          print(path, tag, 'exist, skip')
        else:
          print(path, tag, 'print')
          hdc_print(tag) # 先打印。失败则抛出异常、不写文件
          with open(path, "w", encoding="UTF-8") as ofs:
            ofs.write(tag)
          cnt += 1 # 计数，调试用


def main():
  global g_contest_id
  while True:
    try:
      cookies = login(g_contest_id, g_username, g_password)
      # 登录失败则cookies为None
      while True:
        rank_list(cookies, g_contest_id)
        print('wait 30 seconds...')
        time.sleep(30) # OJ缓存20更新一次，等待过短意义也不大
    except KeyboardInterrupt: # 响应Ctrl+C
      sys.exit(0)
    except:
      print('retry login in 10 seconds...')
      time.sleep(10)


if __name__ == '__main__':
  # hdc_print("A12-M-FIRST") # 开发调试
  main()
